home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 17089 < prev    next >
Encoding:
Text File  |  1996-08-05  |  42.5 KB  |  1,046 lines

  1. Path: sun.soe.clarkson.edu!cline
  2. From: cline@sun.soe.clarkson.edu (Marshall Cline)
  3. Newsgroups: comp.lang.c++
  4. Subject: C++ FAQ: posting #2/4
  5. Followup-To: comp.lang.c++
  6. Date: 13 Apr 1996 17:41:10 GMT
  7. Organization: Paradigm Shift, Inc (technology consulting)
  8. Sender: cline@sun.soe.clarkson.edu
  9. Distribution: world
  10. Expires: +1 month
  11. Message-ID: <4koovm$l5u@library.erc.clarkson.edu>
  12. Reply-To: cline@parashift.com (Marshall Cline)
  13. NNTP-Posting-Host: sun.soe.clarkson.edu
  14. Summary: Please read this before posting to comp.lang.c++
  15. Archive-name: C++-faq/part2_4
  16.  
  17. comp.lang.c++ Frequently Asked Questions list (with answers, fortunately).
  18. Copyright (C) 1991-96 Marshall P. Cline, Ph.D.
  19. Posting 2 of 4.
  20. Posting #1 explains copying permissions, (no)warranty, table-of-contents, etc
  21.  
  22. ==============================================================================
  23. SECTION 9: Freestore management
  24. ==============================================================================
  25.  
  26. Q37: Does "delete p" delete the pointer "p", or the pointed-to-data, "*p"?
  27.  
  28. The pointed-to-data.
  29.  
  30. "delete" really means "delete the thing pointed to by."  The same abuse of
  31. English occurs when "free"ing the memory pointed to by a ptr in C ("free(p)"
  32. really means "free_the_stuff_pointed_to_by(p)").
  33.  
  34. ==============================================================================
  35.  
  36. Q38: Can I "free()" pointers allocated with "new"?  Can I "delete" pointers
  37.    alloc'd with "malloc()"?
  38.  
  39. NO!
  40.  
  41. It is perfectly legal, moral, and wholesome to use malloc/free and new/delete
  42. in the same program, but it is illegal, immoral, and despicable to 'free' a
  43. pointer allocated via 'new', or to 'delete' a pointer allocated via 'malloc'.
  44.  
  45. BEWARE!  I occasionally get email from people telling me that it works ok for
  46. them on machine X and compiler Y.  I don't care if you're just working with an
  47. array of char; do NOT do this!  If you allocated via 'p = new char[n]', you
  48. MUST use 'delete[] p'.  You must NOT use 'delete p', nor 'free(p)'.  Both these
  49. could fail if the code was ported to a new machine, a new compiler, or even a
  50. new version of the same compiler.
  51.  
  52. You have been warned.
  53.  
  54. ==============================================================================
  55.  
  56. Q39: Why should I use "new" instead of trustworthy old malloc()?
  57.  
  58. Constructors/destructors, type safety, overridability.
  59.  
  60. Constructors/destructors: unlike "malloc(sizeof(Fred))", "new Fred()" calls
  61. Fred's constructor.  Similarly, "delete p" calls "*p"'s destructor.
  62.  
  63. Type safety: malloc() returns a "void*" which isn't type safe.  "new Fred()"
  64. returns a ptr of the right type (a "Fred*").
  65.  
  66. Overridability: "new" is an operator that can be overridden by a class, while
  67. "malloc" is not overridable on a per-class basis.
  68.  
  69. ==============================================================================
  70.  
  71. Q40: Why doesn't C++ have a "realloc()" along with "new" and "delete"?
  72.  
  73. To save you from disaster.
  74.  
  75. When realloc() has to copy the allocation, it uses a BITWISE copy operation,
  76. which will tear most C++ objects to shreds.  C++ objects should be allowed to
  77. copy themselves: they use their own copy constructor or assignment operator.
  78.  
  79. ==============================================================================
  80.  
  81. Q41: How do I allocate / unallocate an array of things?
  82.  
  83. Use new[] and delete[]:
  84.  
  85.     Fred* p = new Fred[100];
  86.     //...
  87.     delete [] p;
  88.  
  89. Any time you use the "[...]" in the "new" expression, you *!*MUST*!* use "[]"
  90. in the "delete" statement.  This syntax is necessary because there is no
  91. syntactic difference between a pointer to a thing and a pointer to an array of
  92. things (something we inherited from C).
  93.  
  94. ==============================================================================
  95.  
  96. Q42: What if I forget the "[]" when "delete"ing array allocated via "new
  97.    Fred[n]"?
  98.  
  99. All life comes to a catastrophic end.
  100.  
  101. It is the programmer's --not the compiler's-- responsibility to get the
  102. connection between new[] and delete[] correct.  If you get it wrong, neither a
  103. compile-time nor a run-time error message will be generated by the compiler.
  104. Heap corruption is a likely result.  Or worse.  Your program will probably die.
  105.  
  106. ==============================================================================
  107.  
  108. Q43: Is it legal (and moral) for a member function to say "delete this"?
  109.  
  110. As long as you're careful, you'll be ok.
  111.  
  112. Here's how I define "careful":
  113. 1) You're absolutely 100% positive sure that "this" was allocated via "new"
  114.    (not by "new[]", nor by placement "new", not a local object on the stack,
  115.    not a global, not a member of another object; but by plain ordinary "new").
  116. 2) You're absolutely 100% positive sure that your member function will be
  117.    the last member function invoked on this object.
  118. 3) After you do the suicide thing ("delete this;"), you must not touch any
  119.    piece of "this" object, including data or methods.
  120. 4) After you do the suicide thing ("delete this;"), you must not touch the
  121.    "this" pointer.  In other words, you must not examine it, compare it with
  122.    another pointer or with NULL, print it, cast it, do anything with it.
  123.  
  124. Naturally the usual caveats apply in cases where your "this" pointer is a
  125. pointer to a base class and the destructor isn't virtual.
  126.  
  127. ==============================================================================
  128.  
  129. Q44: How do I allocate multidimensional arrays using new?
  130.  
  131. There are many ways to do this, depending on how flexible you want the array
  132. sizing to be.  On one extreme, if you know all the dimensions at compile-time,
  133. you can allocate multidimensional arrays statically (as in C):
  134.  
  135.     class Fred { /*...*/ };
  136.  
  137.     void manipulateArray()
  138.     {
  139.       Fred matrix[10][20];
  140.  
  141.       //use matrix[i][j]...
  142.  
  143.       //no need for explicit deallocation
  144.     }
  145.  
  146. On the other extreme, if you want to allow the various slices of the matrix to
  147. have a different sizes, you can allocate everything off the freestore:
  148.  
  149.     void manipulateArray(unsigned nrows, unsigned ncols[])
  150.     //'nrows' is the number of rows in the array.
  151.     //therefore valid row numbers are from 0 to nrows-1 inclusive.
  152.     //'ncols[r]' is the number of columns in row 'r' ('r' in [0..nrows-1]).
  153.     {
  154.       Fred** matrix = new Fred*[nrows];
  155.       for (unsigned r = 0; r < nrows; ++r)
  156.         matrix[r] = new Fred[ ncols[r] ];
  157.  
  158.       //use matrix[i][j]...
  159.  
  160.       //deletion is the opposite of allocation:
  161.       for (r = nrows; r > 0; --r)
  162.         delete [] matrix[r-1];
  163.       delete [] matrix;
  164.     }
  165.  
  166. ==============================================================================
  167.  
  168. Q45: Does C++ have arrays whose length can be specified at run-time?
  169.  
  170. Yes, in the sense that STL has a vector template that provides this behavior.
  171. See on "STL" in the "Libraries" section.
  172.  
  173. No, in the sense that built-in array types need to have their length specified
  174. at compile time.
  175.  
  176. Yes, in the sense that even built-in array types can specify the first index
  177. bounds at run-time.  E.g., comparing with the previous FAQ, if you only need
  178. the first array dimension to vary, then you can just ask new for an array of
  179. arrays (rather than an array of pointers to arrays):
  180.  
  181.     const unsigned ncols = 100;
  182.     //'ncols' is not a run-time variable (number of columns in the array)
  183.  
  184.     class Fred { /*...*/ };
  185.  
  186.     void manipulateArray(unsigned nrows)
  187.     //'nrows' is a run-time variable (number of rows in the array)
  188.     {
  189.       Fred (*matrix)[ncols] = new Fred[nrows][ncols];
  190.  
  191.       //use matrix[i][j]
  192.  
  193.       //deletion is the opposite of allocation:
  194.       delete [] matrix;
  195.     }
  196.  
  197. You can't do this if you need anything other than the first dimension
  198. of the array to change at run-time.
  199.  
  200. ==============================================================================
  201.  
  202. Q46: How can I ensure objects of my class are always created via "new" rather
  203.    than as locals or global/static objects?
  204.  
  205. Make sure the class's constructors are "private:", and define "friend" or
  206. "static" fns that return a ptr to the objects created via "new" (make the
  207. constructors "protected:" if you want to allow derived classes).
  208.  
  209.     class Fred {    //only want to allow dynamicly allocated Fred's
  210.     public:
  211.       static Fred* create()                 { return new Fred();     }
  212.       static Fred* create(int i)            { return new Fred(i);    }
  213.       static Fred* create(const Fred& fred) { return new Fred(fred); }
  214.       virtual ~Fred();
  215.     private:
  216.       Fred();
  217.       Fred(int i);
  218.       Fred(const Fred& fred);
  219.     };
  220.  
  221.     main()
  222.     {
  223.       Fred* p = Fred::create(5);
  224.       //...
  225.       delete p;
  226.     }
  227.  
  228. ==============================================================================
  229. SECTION 10: Debugging and error handling
  230. ==============================================================================
  231.  
  232. Q47: How can I handle a constructor that fails?
  233.  
  234. Throw an exception.
  235.  
  236. Constructors don't have a return type, so it's not possible to use error codes.
  237. The best way to signal constructor failure is therefore to throw an exception.
  238.  
  239. Before C++ had exceptions, we signaled constructor failure by putting the
  240. object into a "half baked" state (e.g., by setting an internal status bit).
  241. There was a query ("inspector") method to check this bit, that allowed clients
  242. to discover whether they had a live object.  Other member functions would also
  243. check this bit, and, if the object wasn't really alive, do a no-op (or perhaps
  244. something more obnoxious such as "abort()").  This was really ugly.
  245.  
  246. ==============================================================================
  247.  
  248. Q48: How should I handle resources if my constructors may throw exceptions?
  249.  
  250. Every data member inside your object should clean up its own mess.
  251.  
  252. If a constructor throws an exception, the object's destructor is NOT run.  If
  253. your object has already done something that needs to be undone (such as
  254. allocating some memory, opening a file, or locking a semaphore), this "stuff
  255. that needs to be undone" MUST be remembered by a data member inside the object.
  256.  
  257. For example, rather than allocating memory into a raw "Fred*" data member, put
  258. the allocated memory into a "smart pointer" member object, and the destructor
  259. of this smart pointer will delete the Fred object when the smart pointer dies.
  260.  
  261. ==============================================================================
  262. SECTION 11: Const correctness
  263. ==============================================================================
  264.  
  265. Q49: What is "const correctness"?
  266.  
  267. A good thing.
  268.  
  269. Const correctness uses the keyword "const" to ensure const objects don't get
  270. mutated.  E.g., if function "f()" accepts a "String", and "f()" wants to
  271. promise not to change the "String", you:
  272.  
  273.  * can either pass by value:    void  f(      String  s   )  { /*...*/ }
  274.  * or by constant reference:    void  f(const String& s   )  { /*...*/ }
  275.  * or by constant pointer:    void  f(const String* sptr)  { /*...*/ }
  276.  * but NOT by non-const ref:    void  f(      String& s   )  { /*...*/ }
  277.  * NOR by non-const pointer:    void  f(      String* sptr)  { /*...*/ }
  278.  
  279. Attempted changes to "s" within a fn that takes a "const String&" are flagged
  280. as compile-time errors; neither run-time space nor speed is degraded.
  281.  
  282. Declaring the "constness" of a parameter is just another form of type safety.
  283. It is almost as if a constant String, for example, "lost" its various mutative
  284. operations.  If you find type safety helps you get systems correct (it does;
  285. especially in large systems), you'll find const correctness helps also.
  286.  
  287. ==============================================================================
  288.  
  289. Q50: Should I try to get things const correct "sooner" or "later"?
  290.  
  291. At the very, very, VERY beginning.
  292.  
  293. Back-patching const correctness results in a snowball effect: every "const" you
  294. add "over here" requires four more to be added "over there."
  295.  
  296. ==============================================================================
  297.  
  298. Q51: What is a "const member function"?
  299.  
  300. A member function that inspects (rather than mutates) its object.
  301.  
  302.     class Fred {
  303.     public:
  304.       void f() const;
  305.     };      // ^^^^^--- this implies "fred.f()" won't change "fred"
  306.  
  307. This means that the ABSTRACT (client-visible) state of the object isn't going
  308. to change (as opposed to promising that the "raw bits of the object's struct
  309. aren't going to change).  C++ compilers aren't allowed to take the "bitwise"
  310. interpretation, since a non-const alias could exist which could modify the
  311. state of the object (gluing a "const" ptr to an object doesn't promise the
  312. object won't change; it promises only that the object won't change VIA THAT
  313. POINTER).
  314.  
  315. "const" member functions are often called "inspectors."  Non-"const" member
  316. functions are often called "mutators."
  317.  
  318. ==============================================================================
  319.  
  320. Q52: What do I do if I want to update an "invisible" data member inside a
  321.    "const" member function?
  322.  
  323. Use "mutable", or use "const_cast".
  324.  
  325. A small percentage of inspectors need to make innocuous changes to data members
  326. (e.g., a "Set" object might want to cache its last lookup in hopes of improving
  327. the performance of its next lookup).  By saying the changes are "inocuous," I
  328. mean that the changes wouldn't be visible from outside the object's interface
  329. (otherwise the method would be a mutator rather than an inspector).
  330.  
  331. When this happens, the data member which will be modified should be marked as
  332. "mutable" (put the "mutable" keyword just before the data member's declaration;
  333. i.e., in the same place where you could put "const").  This tells the compiler
  334. that the data member is allowed to change during a const member function.  If
  335. you can't use "mutable", you can cast away the constness of "this" via
  336. "const_cast".  E.g., in "Set::lookup() const", you might say,
  337.  
  338.     Set* self = const_cast<Set*>(this);
  339.  
  340. After this line, "self" will have the same bits as "this" (e.g., "self==this"),
  341. but "self" is a "Set*" rather than a "const Set*".  Therefore you can use
  342. "self" to modify the object pointed to by "this".
  343.  
  344. ==============================================================================
  345.  
  346. Q53: Does "const_cast" mean lost optimization opportunities?
  347.  
  348. In theory, yes; in practice, no.
  349.  
  350. Even if a compiler outlawed "const_cast", the only way to avoid flushing the
  351. register cache across a "const" member function call would be to ensure that
  352. there are no non-const pointers that alias the object.  This can happen only in
  353. rare cases (when the object is constructed in the scope of the const member fn
  354. invocation, and when all the non-const member function invocations between the
  355. object's construction and the const member fn invocation are statically bound,
  356. and when every one of these invocations is also "inline"d, and when the
  357. constructor itself is "inline"d, and when any member fns the constructor calls
  358. are inline).
  359.  
  360. ==============================================================================
  361. SECTION 12: Inheritance
  362. ==============================================================================
  363.  
  364. Q54: Is inheritance important to C++?
  365.  
  366. Yep.
  367.  
  368. Inheritance is what separates abstract data type (ADT) programming from OOP.
  369.  
  370. ==============================================================================
  371.  
  372. Q55: When would I use inheritance?
  373.  
  374. As a specification device.
  375.  
  376. Human beings abstract things on two dimensions: part-of and kind-of.  A Ford
  377. Taurus is-a-kind-of-a Car, and a Ford Taurus has-a Engine, Tires, etc.  The
  378. part-of hierarchy has been a part of software since the ADT style became
  379. relevant; inheritance adds "the other" major dimension of decomposition.
  380.  
  381. ==============================================================================
  382.  
  383. Q56: How do you express inheritance in C++?
  384.  
  385. By the ": public" syntax:
  386.  
  387.     class Car : public Vehicle {
  388.             //^^^^^^^^---- ": public" is pronounced "is-a-kind-of-a'
  389.       //...
  390.     };
  391.  
  392. We state the above relationship in several ways:
  393.  * Car is "a kind of a" Vehicle
  394.  * Car is "derived from" Vehicle
  395.  * Car is "a specialized" Vehicle
  396.  * Car is the "subclass" of Vehicle
  397.  * Vehicle is the "base class" of Car
  398.  * Vehicle is the "superclass" of Car (this not as common in the C++ community)
  399.  
  400. ==============================================================================
  401.  
  402. Q57: Is it ok to convert a pointer from a derived class to its base class?
  403.  
  404. Yes.
  405.  
  406. A derived class is a specialized version of the base class ("Derived is a
  407. kind-of Base").  The upward conversion is perfectly safe, and happens all the
  408. time (if I am pointing at a car, I am in fact pointing at a vehicle):
  409.  
  410.     void f(Vehicle* v);
  411.     void g(Car* c) { f(c); }    //perfectly safe; no cast
  412.  
  413. Note that the answer to this FAQ assumes we're talking about "public"
  414. inheritance; see below on "private/protected" inheritance for "the other kind".
  415.  
  416. ==============================================================================
  417.  
  418. Q58: Derived* --> Base* works ok; why doesn't Derived** --> Base** work?
  419.  
  420. C++ allows a Derived* to be converted to a Base*, since a Derived object is a
  421. kind of a Base object.  However trying to convert a Derived** to a Base** is
  422. (correctly) flagged as an error (if it was allowed, the Base** could be
  423. dereferenced (yielding a Base*), and the Base* could be made to point to an
  424. object of a DIFFERENT derived class.  This would be an error.
  425.  
  426. As a corollary, an array of Deriveds is-NOT-a-kind-of array of Bases.  At
  427. Paradigm Shift, Inc. we use the following example in our C++ training sessions:
  428.  
  429.                "A bag of apples is NOT a bag of fruit".
  430.  
  431. If a bag of apples COULD be passed as a bag of fruit, someone could put a
  432. banana into the bag of apples!
  433.  
  434. ==============================================================================
  435.  
  436. Q59: Does array-of-Derived is-NOT-a-kind-of array-of-Base mean arrays are
  437.    bad?
  438.  
  439. Yes, "arrays are evil" (jest kidd'n :-).
  440.  
  441. There's a very subtle problem with using raw built-in arrays.  Consider this:
  442.  
  443.     void f(Base* arrayOfBase)
  444.     {
  445.       arrayOfBase[3].memberfn();
  446.     }
  447.  
  448.     main()
  449.     {
  450.       Derived arrayOfDerived[10];
  451.       f(arrayOfDerived);
  452.     }
  453.  
  454. The compiler thinks this is perfectly type-safe, since it can convert a
  455. Derived* to a Base*.  But in reality it is horrendously evil: since Derived
  456. might be larger than Base, the array index in f() not only isn't type safe, it
  457. may not even be pointing at a real object!  In general it'll be pointing
  458. somewhere into the innards of some poor Derived.
  459.  
  460. The root problem is that C++ can't distinguish between a ptr-to-a-thing and a
  461. ptr-to-an-array-of-things.  Naturally C++ "inherited" this feature from C.
  462.  
  463. NOTE: if we had used an array-like CLASS instead of using a raw array (e.g., an
  464. "Array<T>" rather than a "T[]"), this problem would have been properly trapped
  465. as an error at compile time rather than at run-time.
  466.  
  467. ==============================================================================
  468. SUBSECTION 12A: Inheritance -- Virtual functions
  469. ==============================================================================
  470.  
  471. Q60: What is a "virtual member function"?
  472.  
  473. A virtual function allows derived classes to replace the implementation
  474. provided by the base class.  The compiler ensures the replacement is always
  475. called whenever the object in question is actually of the derived class, even
  476. if the object is accessed by a base pointer rather than a derived pointer.
  477. This allows algorithms in the base class to be replaced in the derived class,
  478. even if users don't know about the derived class.
  479.  
  480. Note: the derived class can partially replace ("override") the base class
  481. method (the derived class method can invoke the base class version if desired).
  482.  
  483. ==============================================================================
  484.  
  485. Q61: How can C++ achieve dynamic binding yet also static typing?
  486.  
  487. In the following discussion, "ptr" means either a pointer or a reference.
  488.  
  489. When you have a ptr, there are two types: the (static) type of the ptr, and the
  490. (dynamic) type of the pointed-to object (the object may actually be of a class
  491. that is derived from the class of the ptr).
  492.  
  493. "Static typing" means that the "legality" of the call is checked based on the
  494. static type of the ptr: if the type of the ptr can handle the member fn,
  495. certainly the pointed-to object can handle it as well.
  496.  
  497. "Dynamic binding" means that the "code" that is called is based on the dynamic
  498. type of the pointed-to object.  This is called "dynamic binding," since the
  499. actual code being called is determined dynamically (at run time).
  500.  
  501. ==============================================================================
  502.  
  503. Q62: Should a derived class replace ("override") a non-virtual fn from a base
  504.    class?
  505.  
  506. It's legal, but it ain't moral.
  507.  
  508. Experienced C++ programmers will sometimes redefine a non-virtual fn for
  509. efficiency (the alternate implementation might make better use of the derived
  510. class' resources), or to get around the hiding rule (see below, and ARM
  511. ["Annotated Reference Manual"] sect.13.1).  However the client-visible effects
  512. must be IDENTICAL, since non-virtual fns are dispatched based on the static
  513. type of the ptr/ref rather than the dynamic type of the pointed-to/referenced
  514. object.
  515.  
  516. ==============================================================================
  517.  
  518. Q63: What's the meaning of, "Warning: Derived::f(int) hides Base::f(float)"?
  519.  
  520. It means you're going to die.
  521.  
  522. Here's the mess you're in: if Derived declares a member function named "f", and
  523. Base declares a member function named "f" with a different signature (e.g.,
  524. different parameter types and/or constness), then the Base "f" is "hidden"
  525. rather than "overloaded" or "overridden" (even if the Base "f" is virtual).
  526.  
  527. Here's how you get out of the mess: Derived must redefine the Base member
  528. function(s) that are hidden (even if they are non-virtual).  Normally this
  529. re-definition merely calls the appropriate Base member function.  E.g.,
  530.  
  531.     class Base {
  532.     public:
  533.       void f(int);
  534.     };
  535.  
  536.     class Derived : public Base {
  537.     public:
  538.       void f(double);
  539.       void f(int i) { Base::f(i); }
  540.     };             // ^^^^^^^^^^--- redefinition merely calls Base::f(int)
  541.  
  542. ==============================================================================
  543. SUBSECTION 12B: Inheritance -- Conformance
  544. ==============================================================================
  545.  
  546. Q64: Should I hide public member fns inherited from my base class?
  547.  
  548. Never, never, never do this.  Never.  NEVER!
  549.  
  550. Attempting to hide (eliminate, revoke) inherited public member functions is an
  551. all-too-common design error.  It usually stems from muddy thinking.
  552.  
  553. ==============================================================================
  554.  
  555. Q65: Is a "Circle" a kind-of an "Ellipse"?
  556.  
  557. Not if Ellipse promises to be able to change its size asymmetrically.
  558.  
  559. For example, suppose Ellipse has a "setSize(x,y)" method, and suppose this
  560. method promises "the Ellipse's width() will be x, and its height() will be y".
  561. In this case, Circle can't be a kind-of Ellipse.  Simply put, if Ellipse can do
  562. something Circle can't, then Circle can't be a kind of Ellipse.
  563.  
  564. This leaves two potential (valid) relationships between Circle and Ellipse:
  565.  * Make Circle and Ellipse completely unrelated classes.
  566.  * Derive Circle and Ellipse from a base class representing "Ellipses that
  567.    can't NECESSARILY perform an unequal-setSize operation."
  568.  
  569. In the first case, Ellipse could be derived from class "AsymmetricShape" (with
  570. setSize(x,y) being introduced in AsymmetricShape), and Circle could be derived
  571. from "SymmetricShape," which has a setSize(size) member fn.
  572.  
  573. In the second case, class "Oval" could only have "setSize(size)" which sets
  574. both the "width()" and the "height()" to "size", then derive both Ellipse and
  575. Circle from Oval.  Ellipse --but not Circle-- adds the "setSize(x,y)" operation
  576. (see the "hiding rule" for a caveat if the same method name "setSize()" is used
  577. for both operations).
  578.  
  579. ==============================================================================
  580.  
  581. Q66: Are there other options to the "Circle is/isnot kind-of Ellipse"
  582.    dilemma?
  583.  
  584. If you claim that all Ellipses can be squashed asymmetrically, and you claim
  585. that Circle is a kind-of Ellipse, and you claim that Circle can't be squashed
  586. asymmetrically, clearly you've got to adjust (revoke, actually) one of your
  587. claims.  Thus you've either got to get rid of "Ellipse::setSize(x,y)", get rid
  588. of the inheritance relationship between Circle and Ellipse, or admit that your
  589. "Circle"s aren't necessarily circular.
  590.  
  591. Here are the two most common traps new OO/C++ programmers regularly fall into.
  592. They attempt to use coding hacks to cover up a broken design (they redefine
  593. Circle::setSize(x,y) to throw an exception, call "abort()", or choose the
  594. average of the two parameters, or to be a no-op).  Unfortunately all these
  595. hacks will surprise users, since users are expecting "width() == x" and
  596. "height() == y".
  597.  
  598. The only rational way out of this would be to weaken the promise made by
  599. Ellipse's "setSize(x,y)" (e.g., you'd have to change it to, "This method MIGHT
  600. set width() to x and height() to y, or it might do NOTHING").  Unfortunately
  601. this dilutes the contract into dribble, since the user can't rely on any
  602. meaningful behavior.  The whole hierarchy therefore begins to be worthless
  603. (it's hard to convince someone to use an object if you have to shrug your
  604. shoulders when asked what the object does for them).
  605.  
  606. ==============================================================================
  607.  
  608. Q67: But I have a Ph.D. in Mathematics, and I'm SURE a Circle is a kind of an
  609.    Ellipse!  Does this mean Marshall Cline is stupid?  Or that C++ is stupid?  Or
  610.    that OO is stupid?
  611.  
  612. Actually, it doesn't mean any of these things.
  613.  
  614. Look, I have received and answered dozens of passionate email messages about
  615. this subject.  I have taught it hundreds of times to thousands of software
  616. professionals all over the place.  I know this goes against your intuition.
  617. But trust me; your intuition is just plain wrong.
  618.  
  619. The real problem is your intuitive notion of "kind of" doesn't match the OO
  620. notion of proper inheritance (technically called "subtyping").  The bottom line
  621. is that you want the derived class objects to be substitutable for the base
  622. class objects.  In the case of Circle/Ellipse, the "setSize(x,y)" method
  623. violates this substitutability.
  624.  
  625. You have three choices: remove the setSize(x,y) method from Ellipse (thus
  626. breaking existing code that uses that method), or allow a Circle to have a
  627. different height than width (an assymetrical circle; hmmm), or drop the
  628. inheritance relationship.  Sorry, but there simply are no other choices (some
  629. people mention that both Circle and Ellipse could be siblings derived from a
  630. third common base class, but that's just a variant of the third option above).
  631.  
  632. Another way to say this is that you have to either make the base class weaker
  633. (in this case, braindamage Ellipse to the point that you can't set its width
  634. and height to different values), or make the derived class stronger (in this
  635. case, empower a Circle with the ability to be both symmetric and, ahem,
  636. assymetric).  Since neither of these is very satisfying in practice, one
  637. normally simply removes the inheritance relationship.  If the inheritance
  638. relationship simply HAS to exist, you often need to remove the mutator methods
  639. (setHeight(y), setWidth(x), and setSize(x,y)).
  640.  
  641. ==============================================================================
  642.  
  643. Q68: But my problem doesn't have anything to do with circles and ellipses, so
  644.    what good is that silly example to me?
  645.  
  646. Ahhh, there's the rub.  You THINK the circle/ellipse example is just a silly
  647. example.  But in reality, YOUR problem is an isomorphism to that example.
  648.  
  649. I don't care what your inheritance problem is, but all (yes all) bad
  650. inheritances boil down to the circle-is-not-a-kind-of-ellipse example.
  651.  
  652. Here's why: Bad inheritances always have a base class with an extra capability
  653. (often an extra method or two) that a derived class can't satisfy.  You've
  654. either got to make the base class weaker, make the derived class stronger, or
  655. eliminate the proposed inheritance relationship.  I've seen lots and lots and
  656. lots of these bad inheritance proposals, and believe me, they all boil down to
  657. the circle/ellipse problem.
  658.  
  659. If you truly understand the circle/ellipse problem, you'll be able to recognize
  660. bad inheritance everywhere.  If you don't understand what's going on with the
  661. circle/ellipse problem, the chances are high that you'll make some very serious
  662. and very expensive inheritance mistakes.
  663.  
  664. ==============================================================================
  665. SUBSECTION 12C: Inheritance -- Access rules
  666. ==============================================================================
  667.  
  668. Q69: Why can't my derived class access "private" things from my base class?
  669.  
  670. To protect you from future changes to the base class.
  671.  
  672. Derived classes do not get access to private members of a base class.  This
  673. effectively "seals off" the derived class from any changes made to the private
  674. members of the base class.
  675.  
  676. ==============================================================================
  677.  
  678. Q70: What's the difference between "public:", "private:", and "protected:"?
  679.  
  680. "Private:" is discussed in the previous section, and "public:" means "anyone
  681. can access it."  The third option, "protected:", makes a member (either data
  682. member or member fn) accessible to subclasses.
  683.  
  684. ==============================================================================
  685.  
  686. Q71: How can I protect subclasses from breaking when I change internal parts?
  687.  
  688. A class has two distinct interfaces for two distinct sets of clients:
  689.  * its "public:" interface serves unrelated classes.
  690.  * its "protected:" interface serves derived classes.
  691.  
  692. Unless you expect all your subclasses to be built by your own team, you should
  693. consider making your base class's bits be "private:", and use "protected:"
  694. inline access functions to access these data.  This way the private bits can
  695. change, but the derived class's code won't break unless you change the
  696. protected access functions.
  697.  
  698. ==============================================================================
  699. SUBSECTION 12D: Inheritance -- Constructors and destructors
  700. ==============================================================================
  701.  
  702. Q72: When my base class's constructor calls a virtual function, why doesn't my
  703.    derived class's override of that virtual function get invoked?
  704.  
  705. During the Base class's constructor, the object isn't yet a Derived, so if
  706. "Base::Base()" calls a virtual function "virt()", the "Base::virt()" will be
  707. invoked, even if "Derived::virt()" exists.
  708.  
  709. Similarly, during Base's destructor, the object is no longer a Derived, so when
  710. Base::~Base() calls "virt()", "Base::virt()" gets control, NOT the
  711. "Derived::virt()" override.
  712.  
  713. You'll quickly see the wisdom of this approach when you imagine the disaster if
  714. "Derived::virt()" touched a member object from the Derived class.
  715.  
  716. ==============================================================================
  717.  
  718. Q73: Does a derived class destructor need to explicitly call the base
  719.    destructor?
  720.  
  721. No, never explicitly call a destructor (where "never" means "rarely").
  722.  
  723. A derived class's destructor (whether or not you explicitly define one)
  724. AUTOMATICALLY invokes the destructors for member objects and base class
  725. subobjects.  Member objects are destroyed in the reverse order they appear
  726. within the class, then base class subobjects are destroyed in the reverse order
  727. that they appear in the class's list of base classes.
  728.  
  729. You should explicitly call a destructor ONLY in esoteric situations, such as
  730. when destroying an object created by the "placement new operator."
  731.  
  732. ==============================================================================
  733. SUBSECTION 12E: Inheritance -- Private and protected inheritance
  734. ==============================================================================
  735.  
  736. Q74: How do you express "private inheritance"?
  737.  
  738. When you use ": private" instead of ": public."  E.g.,
  739.  
  740.     class Foo : private Bar {
  741.       //...
  742.     };
  743.  
  744. ==============================================================================
  745.  
  746. Q75: How are "private inheritance" and "composition" similar?
  747.  
  748. Private inheritance is a syntactic variant of composition (has-a).
  749.  
  750. E.g., the "car has-a engine" relationship can be expressed using composition:
  751.  
  752.     class Engine {
  753.     public:
  754.       Engine(int numCylinders);
  755.       void start();            //starts this Engine
  756.     };
  757.  
  758.     class Car {
  759.     public:
  760.       Car() : e_(8) { }        //initializes this Car with 8 cylinders
  761.       void start() { e_.start(); }    //start this Car by starting its engine
  762.     private:
  763.       Engine e_;
  764.     };
  765.  
  766. The same "has-a" relationship can also be expressed using private inheritance:
  767.  
  768.     class Car : private Engine {
  769.     public:
  770.       Car() : Engine(8) { }        //initializes this Car with 8 cylinders
  771.       Engine::start;        //start this Car by starting its engine
  772.     };
  773.  
  774. There are several similarities between these two forms of composition:
  775.  * in both cases there is exactly one Engine member object contained in a Car.
  776.  * in neither case can users (outsiders) convert a Car* to an Engine*.
  777.  
  778. There are also several distinctions:
  779.  * the first form is needed if you want to contain several Engines per Car.
  780.  * the second form can introduce unnecessary multiple inheritance.
  781.  * the second form allows members of Car to convert a Car* to an Engine*.
  782.  * the second form allows access to the "protected" members of the base class.
  783.  * the second form allows Car to override Engine's virtual functions.
  784.  
  785. Note that private inheritance is usually used to gain access into the
  786. "protected:" members of the base class, but this is usually a short-term
  787. solution (translation: a band-aid; see below).
  788.  
  789. ==============================================================================
  790.  
  791. Q76: Which should I prefer: composition or private inheritance?
  792.  
  793. Composition.
  794.  
  795. Normally you don't WANT to have access to the internals of too many other
  796. classes, and private inheritance gives you some of this extra power (and
  797. responsibility).  But private inheritance isn't evil; it's just more expensive
  798. to maintain, since it increases the probability that someone will change
  799. something that will break your code.
  800.  
  801. A legitimate, long-term use for private inheritance is when you want to build a
  802. class Fred that uses code in a class Wilma, and the code from class Wilma needs
  803. to invoke methods from your new class, Fred.  In this case, Fred calls
  804. non-virtuals in Wilma, and Wilma calls (usually pure) virtuals in itself, which
  805. are overridden by Fred.  This would be much harder to do with composition.
  806.  
  807.     class Wilma {
  808.     protected:
  809.       void fredCallsWilma()
  810.         { cout << "Wilma::fredCallsWilma()\n"; wilmaCallsFred(); }
  811.       virtual void wilmaCallsFred() = 0;
  812.     };
  813.  
  814.     class Fred : private Wilma {
  815.     public:
  816.       void barney()
  817.         { cout << "Fred::barney()\n"; Wilma::fredCallsWilma(); }
  818.     protected:
  819.       virtual void wilmaCallsFred()
  820.         { cout << "Fred::wilmaCallsFred()\n"; }
  821.     };
  822.  
  823. ==============================================================================
  824.  
  825. Q77: Should I pointer-cast from a "privately" derived class to its base
  826.    class?
  827.  
  828. Generally, No.
  829.  
  830. From a method or friend of a privately derived class, the relationship to the
  831. base class is known, and the upward conversion from PrivatelyDer* to Base* (or
  832. PrivatelyDer& to Base&) is safe; no cast is needed or recommended.
  833.  
  834. However users of PrivateDer should avoid this unsafe conversion, since it is
  835. based on a "private" decision of PrivateDer, and is subject to change without
  836. notice.
  837.  
  838. ==============================================================================
  839.  
  840. Q78: How is protected inheritance related to private inheritance?
  841.  
  842. Similarities: both allow overriding virtuals in the private/protected base
  843. class, neither claims the derived is a kind-of its base.
  844.  
  845. Dissimilarities: protected inheritance allows derived classes of derived
  846. classes to know about the inheritance relationship (it exposes your grand kids
  847. to your implementation details).  This has both benefits (it allows subclasses
  848. of the protected derived class to exploit the relationship to the protected
  849. base class) and costs (the protected derived class can't change the
  850. relationship without potentially breaking further derived classes).
  851.  
  852. Protected inheritance uses the ": protected" syntax:
  853.  
  854.     class Car : protected Engine {
  855.       //...
  856.     };
  857.  
  858. ==============================================================================
  859.  
  860. Q79: What are the access rules with "private" and "protected" inheritance?
  861.  
  862. Take these classes as examples:
  863.  
  864.     class B                    { /*...*/ };
  865.     class D_priv : private   B { /*...*/ };
  866.     class D_prot : protected B { /*...*/ };
  867.     class D_publ : public    B { /*...*/ };
  868.     class UserClass            { B b; /*...*/ };
  869.  
  870. None of the subclasses can access anything that is private in B.  In D_priv,
  871. the public and protected parts of B are "private".  In D_prot, the public and
  872. protected parts of B are "protected".  In D_publ, the public parts of B are
  873. public and the protected parts of B are protected (D_publ is-a-kind-of-a B).
  874. Class "UserClass" can access only the public parts of B, which "seals off"
  875. UserClass from B.
  876.  
  877. To make a public member of B so it is public in D_priv or D_prot, state the
  878. name of the member with a "B::" prefix.  E.g., to make member "B::f(int,float)"
  879. public in D_prot, you would say:
  880.  
  881.     class D_prot : protected B {
  882.     public:
  883.       B::f;    //note: not  "B::f(int,float)"
  884.     };
  885.  
  886. ==============================================================================
  887. SECTION 13: Abstraction
  888. ==============================================================================
  889.  
  890. Q80: What's the big deal of separating interface from implementation?
  891.  
  892. Interfaces are a company's most valuable resources.  Designing an interface
  893. takes longer than whipping together a concrete class which fulfills that
  894. interface.  Furthermore interfaces require the time of more expensive people.
  895.  
  896. Since interfaces are so valuable, they should be protected from being tarnished
  897. by data structures and other implementation artifacts.  Thus you should
  898. separate interface from implementation.
  899.  
  900. ==============================================================================
  901.  
  902. Q81: How do I separate interface from implementation in C++ (like Modula-2)?
  903.  
  904. Use an ABC (see next FAQ).
  905.  
  906. ==============================================================================
  907.  
  908. Q82: What is an ABC ("abstract base class")?
  909.  
  910. At the design level, an ABC corresponds to an abstract concept.  If you asked a
  911. Mechanic if he repaired Vehicles, he'd probably wonder what KIND-OF Vehicle you
  912. had in mind.  Chances are he doesn't repair space shuttles, ocean liners,
  913. bicycles, or nuclear submarines.  The problem is that the term "Vehicle" is an
  914. abstract concept (e.g., you can't build a "vehicle" unless you know what kind
  915. of vehicle to build).  In C++, class Vehicle would be an ABC, with Bicycle,
  916. SpaceShuttle, etc, being subclasses (an OceanLiner is-a-kind-of-a Vehicle).  In
  917. real-world OOP, ABCs show up all over the place.
  918.  
  919. As programming language level, an ABC is a class that has one or more pure
  920. virtual member functions (see next FAQ).  You cannot make an object (instance)
  921. of an ABC.
  922.  
  923. ==============================================================================
  924.  
  925. Q83: What is a "pure virtual" member function?
  926.  
  927. A member function declaration that turns a normal class into an abstract class
  928. (i.e., an ABC).  You normally only implement it a derived class.
  929.  
  930. Some member functions exist in concept; they don't have any reasonable
  931. definition.  E.g., suppose I asked you to draw a Shape at location (x,y) that
  932. has size 7.  You'd ask me "what kind of shape should I draw?" (circles,
  933. squares, hexagons, etc, are drawn differently).  In C++, we must indicate the
  934. existence of the "draw()" method (so users can call it when they have a Shape*
  935. or a Shape&), but we recognize it can (logically) be defined only in
  936. subclasses: 
  937.  
  938.     class Shape {
  939.     public:
  940.       virtual void draw() const = 0;
  941.       //...                     ^^^--- "= 0" means it is "pure virtual"
  942.     };
  943.  
  944. This pure virtual function makes "Shape" an ABC.  If you want, you can think of
  945. the "= 0" syntax as if the code were at the NULL pointer.  Thus "Shape"
  946. promises a service to its users, yet Shape isn't able to provide any code to
  947. fulfill that promise.  This ensures any actual object created from a [concrete]
  948. class derived of Shape *WILL* have the indicated member fn, even though the
  949. base class doesn't have enough information to actually DEFINE it yet.
  950.  
  951. Note that it is possible to provide a definition for a pure virtual function,
  952. but this usually confuses novices and is best avoided until later.
  953.  
  954. ==============================================================================
  955.  
  956. Q84: How can I provide printing for an entire hierarchy of classes?
  957.  
  958. Provide a friend operator<< that calls a protected virtual function:
  959.  
  960.     class Base {
  961.     public:
  962.       friend ostream& operator<< (ostream& o, const Base& b)
  963.         { b.print(o); return o; }
  964.       //...
  965.     protected:
  966.       virtual void print(ostream& o) const;  //or "=0;" if "Base" is an ABC
  967.     };
  968.  
  969.     class Derived : public Base {
  970.     protected:
  971.       virtual void print(ostream& o) const;
  972.     };
  973.  
  974. Now all subclasses of Base merely provide their own "print(ostream&) const"
  975. member function (they all share the common "<<" operator).  This technique
  976. allows friends to ACT as if they supported dynamic binding.
  977.  
  978. ==============================================================================
  979.  
  980. Q85: When should my destructor be virtual?
  981.  
  982. When you may "delete" a derived object via a base pointer.
  983.  
  984. Virtual fns bind to the code associated with the class of the object, rather
  985. than with the class of the pointer/ref.  When you say "delete basePtr", and the
  986. base class has a virtual destructor, the destructor that gets invoked is the
  987. one associated with the type of the object *basePtr, rather than the one
  988. associated with the type of the pointer.  This is generally A Good Thing.
  989.  
  990. To make life easy for you, the only time you wouldn't want to make a class's
  991. destructor virtual is if that class has NO virtual fns, since the introduction
  992. of the first virtual fn imposes some space overhead in each object (typically
  993. one machine word).  This is how the compiler implements the magic of dynamic
  994. binding; it usually boils down to an extra ptr per object called the "virtual
  995. table pointer" or "vptr".
  996.  
  997. ==============================================================================
  998.  
  999. Q86: What is a "virtual constructor"?
  1000.  
  1001. An idiom that allows you to do something that C++ doesn't directly support.
  1002.  
  1003. You can get the effect of virtual constructor by a virtual "createCopy()"
  1004. member fn (for copy constructing), or a virtual "createSimilar()" member fn
  1005. (for the default constructor).
  1006.  
  1007.     class Shape {
  1008.     public:
  1009.       virtual ~Shape() { }        //see on "virtual destructors" for more
  1010.       virtual void draw() = 0;
  1011.       virtual void move() = 0;
  1012.       //...
  1013.       virtual Shape* createCopy() const = 0;
  1014.       virtual Shape* createSimilar() const = 0;
  1015.     };
  1016.  
  1017.     class Circle : public Shape {
  1018.     public:
  1019.       Circle* createCopy()    const { return new Circle(*this); }
  1020.       Circle* createSimilar() const { return new Circle(); }
  1021.       //...
  1022.     };
  1023.  
  1024. The invocation of "Circle(*this)" is that of copy construction ("*this" has
  1025. type "const Circle&" in these methods).  "createSimilar()" is similar, but it
  1026. constructs a "default" Circle.
  1027.  
  1028. Users use these as if they were "virtual constructors":
  1029.  
  1030.     void userCode(Shape& s)
  1031.     {
  1032.       Shape* s2 = s.createCopy();
  1033.       Shape* s3 = s.createSimilar();
  1034.       //...
  1035.       delete s2;    //relies on destructor being virtual!!
  1036.       delete s3;    // ditto
  1037.     }
  1038.  
  1039. This fn will work correctly regardless of whether the Shape is a Circle,
  1040. Square, or some other kind-of Shape that doesn't even exist yet.
  1041.  
  1042. --
  1043. Paradigm Shift, Inc. / P.O. Box 5108 / Potsdam, NY  13676
  1044. Technology consulting services
  1045. cline@parashift.com / Voice: 315-353-6100 / FAX: 315-353-6110
  1046.